import { isDefined } from '@vimi/utils-tool'

export default {
  bind(el, binding, _vnode) {
    const inputEl = el.querySelector('input,textarea')
    if (!inputEl) return

    const compositionstartHandler = () => {
      inputEl.inputLocking = true
    }

    const compositionendHandler = () => {
      inputEl.inputLocking = false
      inputEl.dispatchEvent(new Event('input'))
    }

    const inputHandler = () => {
      if (inputEl.inputLocking) return
      const oldVal = inputEl.value

      let dotIndex = 0
      let newVal = oldVal
        .replace('。', '.') // 容忍字符
        .replace(/[^\d.-]/g, '') // 允许的字符
        .replace(/^(-)?\./, (m, p1 = '') => `${p1}0.`) // 首位 '.' 或 '-.'
        .replace(/\./g, () => (dotIndex++ === 0 ? '.' : '')) // 多个 '.'
        .replace(/-/g, (m, p) => (p === 0 ? '-' : '')) // 多个 '-'
        .replace(/^(-)?0+(\d)/, '$1$2') // 开头多余的0

      if (oldVal !== newVal) {
        inputEl.value = newVal
        inputEl.dispatchEvent(new Event('input'))
      }
    }

    const blurHandler = () => {
      const oldVal = inputEl.value
      if (oldVal === '') return

      let newVal = oldVal
      const { min, max, fixed, onMin, onMax, onFixed } = binding.value || {}

      if (isDefined(fixed)) {
        let [int, decimal = ''] = newVal.split('.')
        if (decimal.length > fixed) {
          decimal = decimal.substr(0, fixed)
          newVal = int + (decimal ? `.${decimal}` : '')
          onFixed && onFixed(newVal, fixed)
        }
      }

      let numVal = +newVal

      // 处理最大值
      if (isDefined(max) && numVal > max) {
        numVal = max
        newVal = `${max}`
        onMax && onMax(numVal, max)
      }

      // 处理最小值
      if (isDefined(min) && numVal < min) {
        numVal = min
        newVal = `${min}`
        onMin && onMin(numVal, min)
      }

      // 是否清除小数点后面的0
      const { clear = false } = binding.modifiers || {}
      if (clear && /\./.test(newVal)) {
        newVal = newVal.replace(/0+$/, '')
      }

      newVal = newVal
        .replace(/\.$/, '') // 最后一位是 '.'
        .replace(/^-(0)?$/, '$1') // '-' 或 '-0'

      if (oldVal !== newVal) {
        inputEl.value = newVal
        inputEl.dispatchEvent(new Event('input'))
      }
    }

    // 用中文输入法时，输入中文v-model没有同步，输入数字又正常（element可能永久不会同步），所以用composition事件处理
    inputEl.addEventListener('compositionstart', compositionstartHandler)
    inputEl.addEventListener('compositionend', compositionendHandler)

    // 输入时进行字符处理
    inputEl.addEventListener('input', inputHandler)

    // 无法确定用户的输入是否真的应该清除，放在 blur 中进行处理
    inputEl.addEventListener('blur', blurHandler)
  },
}
